#include "Ray3.h"

namespace PocketSurvival::Engine
{
    bool Ray3::Intersection(const BoundingBox &box, float &outValue) const
    {
		if (Position.posX >= box.Min.posX && Position.posX <= box.Max.posX && 
            Position.posY >= box.Min.posY && Position.posY <= box.Max.posY && 
            Position.posZ >= box.Min.posZ && Position.posZ <= box.Max.posZ)
		{
            outValue = 0.0f;
			return true;
		}
        Vector3 vector(-1.0f, -1.0f, -1.0f);
		if (Direction.posX != 0.0f)
		{
			if (Position.posX < box.Min.posX)
			{
				vector.posX = (box.Min.posX - Position.posX) / Direction.posX;
			}
			else if (Position.posX > box.Max.posX)
			{
				vector.posX = (box.Max.posX - Position.posX) / Direction.posX;
			}
		}
		if (Direction.posY != 0.0f)
		{
			if (Position.posY < box.Min.posY)
			{
				vector.posY = (box.Min.posY - Position.posY) / Direction.posY;
			}
			else if (Position.posY > box.Max.posY)
			{
				vector.posY = (box.Max.posY - Position.posY) / Direction.posY;
			}
		}
		if (Direction.posZ != 0.0f)
		{
			if (Position.posZ < box.Min.posZ)
			{
				vector.posZ = (box.Min.posZ - Position.posZ) / Direction.posZ;
			}
			else if (Position.posZ > box.Max.posZ)
			{
				vector.posZ = (box.Max.posZ - Position.posZ) / Direction.posZ;
			}
		}
		if (vector.posX > vector.posY && vector.posX > vector.posZ)
		{
			if (vector.posX < 0.0f)
			{
				return false;
			}
			float num = Position.posZ + vector.posX * Direction.posZ;
			if (num < box.Min.posZ || num > box.Max.posZ)
			{
				return false;
			}
			num = Position.posY + vector.posX * Direction.posY;
			if (num < box.Min.posY || num > box.Max.posY)
			{
				return false;
			}
			outValue = vector.posX;
			return true;
		}
		if (vector.posY > vector.posX && vector.posY > vector.posZ)
		{
			if (vector.posY < 0.0f)
			{
				return false;
			}
			float num2 = Position.posZ + vector.posY * Direction.posZ;
			if (num2 < box.Min.posZ || num2 > box.Max.posZ)
			{
				return false;
			}
			num2 = Position.posX + vector.posY * Direction.posX;
			if (num2 < box.Min.posX || num2 > box.Max.posX)
			{
				return false;
			}
			outValue = vector.posY;
			return true;
		}
		if (vector.posZ < 0.0f)
		{
			return false;
		}
		float num3 = Position.posX + vector.posZ * Direction.posX;
		if (num3 < box.Min.posX || num3 > box.Max.posX)
		{
			return false;
		}
		num3 = Position.posY + vector.posZ * Direction.posY;
		if (num3 < box.Min.posY || num3 > box.Max.posY)
		{
			return false;
		}
		outValue = vector.posZ;
		return true;
    }

    bool Ray3::Intersection(const Plane &plane, float &outValue) const
    {
		float num = Vector3::Dot(Direction, plane.Normal);
		if (num == 0.0f)
		{
			return false;
		}
        outValue = (0.0f - (Vector3::Dot(Position, plane.Normal) + plane.D)) / num;
		return true;
    }

} // namespace PocketSurvival::Engine
